#include "Phidget.h"
#include "PhidgetInterfaceKit.h"
#include "PhidgetManager.h"
#include <stdexcept>
#include "stdio.h"



int Phidget::AttachHandler(CPhidgetHandle handle, void *userdata)
{
	((Phidget *)userdata)->AttachHandler();
	
	return 0;
}


Phidget::Phidget()
{
}


void Phidget::AttachHandler()
{
	if (serialNumber <= 0)
	{
		CPhidget_getSerialNumber(handle, &serialNumber);
		CPhidget_getDeviceType(handle, &deviceType);
	}

	_isAttached = true;
}


//
// Initialize a new phidget with the given handle.
//
Phidget::Phidget(CPhidgetHandle inHandle)
{
	handle = inHandle;
	serialNumber = -1;
	deviceType = NULL;
}


//
// Destroy this phidget object. Remove any handlers we may have in place.
//
Phidget::~Phidget()
{
	CPhidget_set_OnAttach_Handler(handle, NULL, this);
}


//
// Perform common initialization.
//
void Phidget::CommonInit()
{
	CPhidget_set_OnAttach_Handler(handle, AttachHandler, this);
}


//
// Create a new phidget of the appropraite phidget class type.
//
Phidget *Phidget::ConstructPhidget(CPhidgetHandle inHandle, PhidgetManager *manager)
{
	CPhidget_DeviceClass deviceClass;
	Phidget *phidget;
	int serial;
	

	//
	// Get the device class of this phidget so we know what type of c++
	// class to use.
	//
	if (CPhidget_getDeviceClass(inHandle, &deviceClass) != EPHIDGET_OK)
		throw std::runtime_error("Could not determine phidget class during initialization.");	
	if (CPhidget_getSerialNumber(inHandle, &serial) != EPHIDGET_OK)
		throw std::runtime_error("Could not determine phidget serial during initialization.");	

	switch (deviceClass)
	{
		case PHIDCLASS_INTERFACEKIT:
			phidget = new PhidgetInterfaceKit(serial, manager);
			break;

		default:
			throw std::runtime_error("Unknown phidget class during initialization.");
	}
	
	return phidget;
}


//
// Determine if this phidget is currently attached or not.
//
bool Phidget::isAttached()
{
	return _isAttached;
}


//
// Retrieve the serial number of this phidget.
//
int Phidget::SerialNumber()
{
	if (serialNumber == -1)
	{
		CPhidget_getSerialNumber(handle, &serialNumber);
	}
	
	return serialNumber;
}


//
// Retrieve the device type (as a string) of this phidget.
//
const char *Phidget::DeviceType()
{
	if (deviceType != NULL)
	{
		CPhidget_getDeviceType(handle, &deviceType);
	}
	
	return deviceType;
}



//////////////////////////////////////////////////////////////////////
//
// Public virtual methods that should be overridden by subclasses.
//
//////////////////////////////////////////////////////////////////////

//
// Retrieve a list of the properties supported by this phidget.
//
std::list<std::string> Phidget::SupportedProperties()
{
	return std::list<std::string>();
}


//
// Get the value of the named property.
//
std::string Phidget::GetPropertyValue(std::string property)
{
	return std::string("");
}


//
// Set the value of the named property.
//
void Phidget::SetPropertyValue(std::string property, std::string value)
{
}

